/*
 * Copyright (c) 2017年11月01日  by XuanWu Wireless Technology Co., Ltd 
 *             All rights reserved  
 */
package com.zml.service.impl;

import com.zml.entity.sync.SysConfig;
import com.zml.service.EmailService;
import com.zml.utils.FileUtil;
import com.zml.utils.JsonUtil;
import com.zml.utils.ListUtil;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.mail.DefaultAuthenticator;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailAttachment;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.apache.commons.mail.MultiPartEmail;
import org.apache.commons.mail.SimpleEmail;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.mail.internet.MimeUtility;


/**
 * @author <a href="mailto:zhaominglin@wxchina.com">minglin.Zhao</a>
 * @Description
 * @Date 2017/11/1
 * @Version 1.0.0
 */
@Service
public class EmailServiceImpl implements EmailService {

    private static final Logger msgLog = LogManager.getLogger(EmailServiceImpl.class);

    @Autowired
    private SysConfig sysConfig;

    private static String htmlTemplate;
    private int emailTimeout = 8 * 000;//超时时间,单位毫秒,默认为8000.

    @Override
    public SendResult sendEmail(String subject, String content, String... emailTos) {
        return sendHtmlEmail(true, subject, content, emailTos);
    }

    @Override
    public SendResult sendMultiPartEmail(String subject, String content, String attachmentPath, String[] emailTos) {
        try {
            subject = subject + sysConfig.getMsgSign();
            if (ArrayUtils.isEmpty(emailTos)) {
                msgLog.error("sendMultiPartEmail failed emailTos must not be empty");
                return SendResult.buildFailre();
            }
            MultiPartEmail email = new MultiPartEmail();
            email.setHostName(sysConfig.getSmtpHostname());
            email.setSmtpPort(sysConfig.getSmtpPort());
            email.setAuthenticator(new DefaultAuthenticator(sysConfig.getSmtpUsername(), sysConfig.getSmtpPassword()));
            if (sysConfig.isSmtpSslOn()) {
                email.setSSLOnConnect(true);
                email.setSslSmtpPort(String.valueOf(sysConfig.getSmtpSslPort()));
            } else {
                email.setSSLOnConnect(false);
            }
            msgLog.info("sendMultiPartEmail mail: {} to {}", subject, Arrays.toString(emailTos));
            email.setCharset("UTF-8");
            email.setSocketConnectionTimeout(emailTimeout);
            email.setFrom(sysConfig.getEmailFrom());
            email.setSubject(subject);
            email.setMsg(content);
            for (String to : emailTos) {
                email.addTo(to);
            }
            EmailAttachment attachment = new EmailAttachment();
            attachment.setPath(attachmentPath);// 本地文件
            attachment.setDisposition(EmailAttachment.ATTACHMENT);
            attachment.setDescription(MimeUtility.encodeText(subject + ".png"));
            attachment.setName(MimeUtility.encodeText(subject + ".png"));
            email.attach(attachment);
            String sendResult = email.send();
            if (sendResult != null) {
                return SendResult.buildSuccess();
            } else {
                msgLog.error("sendMultiPartEmail failed!");
                return SendResult.buildFailre();
            }
        } catch (Exception e) {
            msgLog.error("sendMultiPartEmail failed: ", e);
        }
        return SendResult.buildFailre();
    }

    @Override
    public SendResult sendImgsEmail(String subject, String content, List<String> imgPaths, String[] emailTos, String[] copyEmails, String[] secretEmails) {
        try {
            if (ArrayUtils.isEmpty(emailTos)) {
                msgLog.error("sendImgsEmail failed emailTos must not be empty");
                return SendResult.buildFailre();
            }
            HtmlEmail email = new HtmlEmail();
            email.setHostName(sysConfig.getSmtpHostname());
            email.setSmtpPort(sysConfig.getSmtpPort());
            email.setAuthenticator(new DefaultAuthenticator(sysConfig.getSmtpUsername(), sysConfig.getSmtpPassword()));
            if (sysConfig.isSmtpSslOn()) {
                email.setSSLOnConnect(true);
                email.setSslSmtpPort(String.valueOf(sysConfig.getSmtpSslPort()));
            } else {
                email.setSSLOnConnect(false);
            }
            msgLog.info("sendImgsEmail mail: {} to {}", subject, Arrays.toString(emailTos));
            email.setCharset("UTF-8");
            email.setSocketConnectionTimeout(emailTimeout);
            email.setFrom(sysConfig.getEmailFrom());
            email.setSubject(subject);
            email.setMsg(content);
            for (String to : emailTos) {
                email.addTo(to);
            }
            if (ArrayUtils.isNotEmpty(copyEmails)) {
                email.addCc(copyEmails);
            }
            if (ArrayUtils.isNotEmpty(secretEmails)) {
                email.addBcc(secretEmails);
            }
            StringBuilder htmlMsg = new StringBuilder();
            if (ListUtil.isNotBlank(imgPaths)) {
                htmlMsg.append("<html><body>");
                for (String imgPath : imgPaths) {
                    String cid = email.embed(new File(imgPath));
                    htmlMsg.append("<img src=\"cid:").append(cid).append("\">");
                }
                htmlMsg.append("</body></html>");
            }
            email.setHtmlMsg(htmlMsg.toString());
            String sendResult = email.send();
            if (sendResult != null) {
                return SendResult.buildSuccess();
            } else {
                msgLog.error("sendImgsEmail failed!");
                return SendResult.buildFailre();
            }
        } catch (Exception e) {
            msgLog.error("sendImgsEmail failed: ", e);
        }
        return SendResult.buildFailre();
    }

    public SendResult sendHtmlEmail(boolean isHtml, String subject, String content, String... emailTos) {
        Email email = new SimpleEmail();
        email.setHostName(sysConfig.getSmtpHostname());
        email.setSmtpPort(sysConfig.getSmtpPort());
        email.setAuthenticator(new DefaultAuthenticator(sysConfig.getSmtpUsername(),sysConfig.getSmtpPassword()));
        if (sysConfig.isSmtpSslOn()) {
            email.setSSLOnConnect(true);
            email.setSslSmtpPort(String.valueOf(sysConfig.getSmtpSslPort()));
        } else {
            email.setSSLOnConnect(false);
        }

        msgLog.info("sendHtmlEmail mail: {} to {}", subject, Arrays.toString(emailTos));
        try {
            email.setCharset("UTF-8");
            email.setSocketConnectionTimeout(emailTimeout);
            email.setFrom(sysConfig.getEmailFrom());
            email.setSubject(subject);
            if (isHtml) {
                email.setContent(toHtml(content), "text/html; charset=utf-8");
            } else {
                email.setMsg(content);
            }
            for (String to : emailTos) {
                email.addTo(to);
            }
            String sendResult = email.send();
            if (sendResult != null) {
                return SendResult.buildSuccess();
            } else {
                msgLog.error("sendHtmlEmail failed!");
                return SendResult.buildFailre();
            }
        } catch (EmailException e) {
            msgLog.error("sendHtmlEmail mail failed: ", e);
        }
        return SendResult.buildFailre();
    }
    public static String toHtml(String content) {
        try {
            if (StringUtils.isBlank(content) || !content.startsWith("{")) {
                return content;
            }
            String htmlContent = htmlTemplate();
            content = content.replaceAll("\"", "\\\"");
            Map<String, String> params = JsonUtil.toMap(content);
            for (Map.Entry<String, String> entry : params.entrySet()) {
                htmlContent = htmlContent.replace(entry.getKey(), entry.getValue());
            }
            return htmlContent;
        } catch (Exception e) {
            e.printStackTrace();
            msgLog.error("fillHtml  failed: ", e);
        }
        return null;
    }
    private static String htmlTemplate() throws IOException {
        if (StringUtils.isBlank(htmlTemplate)) {
            htmlTemplate = FileUtil.readFile("mail_template.txt");
            return htmlTemplate;
        }
        return htmlTemplate;
    }

}
